pub(crate) struct LenghtCounter {
    pub(crate) enabled: bool,
    value: u16,
    max: u16,
}

impl LenghtCounter {
    pub(crate) fn new(max: u16) -> Self {
        Self {
            enabled: false,
            value: 0,
            max: max,
        }
    }

    pub(crate) fn is_active(&self) -> bool {
        self.value > 0
    }

    fn extra_step(frame_step: u8) -> bool {
        // if the last 'step' was a length step return true
        // this is equivalent to (next) frame_step is not a length step
        // whih is true for odd steps
        frame_step % 2 == 1
    }

    pub(crate) fn enable(&mut self, enable: bool, frame_step: u8) {
        let was_enabled = self.enabled;
        // self.step takes the new value of enabled into account
        self.enabled = enable;
        if !was_enabled && Self::extra_step(frame_step) {
            self.step();
        }
    }

    pub(crate) fn set(&mut self, minus_value: u8) {
        self.value = self.max - minus_value as u16;
    }

    pub(crate) fn trigger(&mut self, frame_step: u8) {
        if self.value == 0 {
            self.value = self.max;

            if Self::extra_step(frame_step) {
                self.step();
            }
        }
    }

    pub(crate) fn step(&mut self) {
        if self.enabled && self.value > 0 {
            self.value -= 1;
        }
    }
}
